/*---------------------------------发送和接收函数----------------------------------*/
#include	"ipmsg.h"
#include	"MyIpmsg.h"

void ipmsgswitch(ipmsgdata * data, char * buff)	/*收到的消息内容及对收到的消息的反应*/
{
	char 			* buf = NULL;
	unsigned int 		com_opt;
	int 			fileid;
	char 			filename[PATH_MAX];
	unsigned long long 	size;
	unsigned int 		mtime;
	int 			fileattr;
	char 			* temp = NULL;
	char 			* t = NULL, * t2 = NULL;
	int 			lens=strlen(buff);
	unsigned long		packetnoss;
	unsigned int		offset;
	
	buf = strtok(buff, ":");
	if (buf)
		sscanf(buf, "%d", & (data->version));
	
	buf = strtok(NULL, ":");
	if (buf)
		sscanf(buf, "%d", & (data->packetno));
	
	buf = strtok(NULL, ":");
	if (buf) 
		strncpy(data->sendername, buf, strlen(buf) + 1);
	
	buf = strtok(NULL, ":");
	if (buf) 
		strncpy(data->senderhost, buf, strlen(buf) + 1);
	
	buf = strtok(NULL, ":");
	if (buf)
		sscanf(buf, "%u", & (data->com));
	
	//buf = strchr(NULL, ":");
	buf = buf + strlen(buf) + 1;
	if (buf)
		strncpy(data->append, buf, strlen(buf) + 1);
		//data->append = strdup(buf);
	
	switch ( GET_MODE(data->com)) {
		case IPMSG_NOOPERATION:
			//ipmsgsendbcast(&from,IPMSG_ANSENTRY);
			break;
		case IPMSG_BR_ENTRY:
			if (user_exist( & from, data))
				tail = adduser( & from, tail, data);
			ipmsgsendbcast( & from, IPMSG_ANSENTRY, data);
			break;
		case IPMSG_ANSENTRY:
			if (user_exist( & from, data))
				tail = adduser( & from, tail, data);
			break;
		case IPMSG_BR_EXIT:
			del_user( & from, data);
			break;
		case IPMSG_SENDMSG:
			com_opt = GET_OPT(data->com);
			if (com_opt & IPMSG_SENDCHECKOPT) {
				ipmsgsendbcast( & from, IPMSG_RECVMSG, data);
				if (data->append[0]) {
					printf("get msg from %s(%s)\n", data->sendername, data->ip);
					printf("%s\n(ipmsg)", data->append);
				}
			}
			if (com_opt & IPMSG_FILEATTACHOPT) {
				//data->sendfileheader = strdup(buff + lens + 1);
				strncpy(data->sendfileheader, (buff + lens + 1), strlen(buff + lens + 1) + 1);
				buf = strtok( (data->sendfileheader), "\a");
				
				while (buf) {
					sscanf(buf, "%x", & fileid);
					t = buf;
					t = strstr(t, ":");
					t2 = strstr(t + 1, ":");
					memset(filename, 0, PATH_MAX);
					strncpy(filename, t + 1, t2 - t - 1);
					sscanf(t2 + 1, "%llx:%x", & size, & mtime);
					t2 = strstr(t2 + 1, ":");
					t = strstr(t2 + 1, ":");
					sscanf(t + 1, "%d", & fileattr);
					temp = filename;
					while( (temp = strstr(temp, "::")))
						strncpy(temp + 1, temp + 2, strlen(temp + 2) + 1);
					files[fileid].fileID = fileid;
					strncpy(files[fileid].filename, filename, strlen(filename) + 1);
					files[fileid].size = size;
					files[fileid].mtime = mtime;
					files[fileid].fileattr = fileattr;
					buf = strtok(NULL,"\a");
				}
				
				filenum = fileid + 1;
				memcpy( & trans_file_from[0], & from,  sizeof(from));
				datafortcp = data;
				printf("get files from %s(%s)\n", data->sendername, data->ip);
			}
			break;
		case IPMSG_RECVMSG:
			if ( (unsigned int ) atol(data->append) == pocketnos) {
				sendcheckflag = 0;
				repeatflag = 0;
				recvflag = 1;
			}
			break;
		case IPMSG_GETFILEDATA:
			sscanf(data->append, "%lx:%x:%x", &packetnoss, &fileid, &offset);
			if ( packetnoss == pocketnos) {
				startsendflag = 1;
				FileID = fileid;
			}
			break;
		case IPMSG_GETDIRFILES:
			sscanf(data->append, "%lx:%x", &packetnoss, &fileid);
			if (packetnoss == pocketnos) {
				startsendflag = 1;
				FileID = fileid;
			}
			break;
		case IPMSG_RELEASEFILES:
			if( (unsigned int )atol(data->append) == pocketnos) {
				if (pthread_cancel(id_sendfiles) != 0) {
					perror("pthread_cancel");
					break;
				}
			}
			break;
	}
}

void ipmsgsendbcast(struct sockaddr_in * dest, unsigned int com, ipmsgdata * data)	/*发送消息*/
{
	time_t 			now = time(NULL);
	//static unsigned int 	last_time = 0;
	int 			len;
	
	memset(buffer, 0, MAXSOCKBUF);
	
	//if ( (unsigned int ) now <= last_time)	now = ++last_time;
	//last_time = now;
	
	switch(GET_MODE(com)) {
		case IPMSG_NOOPERATION:
			sprintf(buffer, "1:%u:%s:%s:%u:", (unsigned int ) now, user, hostname, com);
			len = strlen(buffer) + 1;
			break;
		case IPMSG_BR_ENTRY:
			sprintf(buffer, "1:%u:%s:%s:%u:%s%c%s", \
					(unsigned int ) now, user, hostname, com, user, '\a', group);
			len = strlen(buffer) + 1;
			break;
		case IPMSG_ANSENTRY:
			sprintf(buffer, "1:%u:%s:%s:%u:%s%c%s", \
					(unsigned int ) now, user, hostname, com, user, '\a', group);
			len = strlen(buffer) + 1;
			break;
		case IPMSG_BR_EXIT:
			sprintf(buffer, "1:%u:%s:%s:%u:%s%c%s", \
					(unsigned int ) now, user, hostname, com, user, '\a', group);
			len = strlen(buffer) + 1;
			break;
		case IPMSG_RECVMSG:
			sprintf(buffer, "1:%u:%s:%s:%u:%u", (unsigned int ) now, user, hostname, com, data->packetno);
			len = strlen(buffer) + 1;
			break;
		case IPMSG_SENDMSG:
			if (data->append[0] != '\0') {
				sprintf(buffer, "1:%u:%s:%s:%u:%s", (unsigned int ) now, \
						user, hostname, com, data->append);
			}
			else
				sprintf(buffer, "1:%u:%s:%s:%u:", (unsigned int ) now, \
						user, hostname, com);
			len = strlen(buffer) + 1;
			strncpy(buffer + len, data->sendfileheader, strlen(data->sendfileheader) + 1);
			if (GET_OPT(com) & IPMSG_FILEATTACHOPT)
				len += strlen(buffer + len) + 1;
			if (GET_OPT(com) & IPMSG_SENDCHECKOPT) {
				pocketnos = now;
				sendcheckflag = 1;
			}
			else
				sendcheckflag = 0;
			break;
	}
	sendto(soc, buffer, len, 0, (struct sockaddr * ) dest, sizeof(struct sockaddr_in));
}
